package com.jakewharton.rxbinding4.component;

import static com.jakewharton.rxbinding4.internal.Functions.CALLABLE_ALWAYS_TRUE;
import static com.jakewharton.rxbinding4.internal.Functions.PREDICATE_ALWAYS_TRUE;
import static com.jakewharton.rxbinding4.internal.Preconditions.checkNotNull;

import io.reactivex.rxjava3.annotations.CheckReturnValue;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.functions.BiConsumer;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Predicate;
import ohos.agp.components.SearchBar;

import java.util.concurrent.Callable;

/**
 * Static factory methods for creating {@linkplain Observable observables} and {@linkplain Consumer
 * actions}* for {@link SearchBar}.
 */
public final class RxSearchBar {
    /**
     * Create an observable of {@linkplain SearchBarSearchQueryEvent search query events} on {@code
     * view}*.
     * <p>
     * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
     * to free this reference.
     * <p>
     *
     * @param view view
     * @return the observable
     */
    @CheckReturnValue
    @NonNull
    public static Observable<SearchBarSearchQueryEvent> searchQueryChangeEvents(@NonNull SearchBar view) {
        checkNotNull(view, "view == null");
        return new SearchBarQueryChangeEventsOnSubscribe(view, PREDICATE_ALWAYS_TRUE);
    }

    /**
     * Search query change events observable
     *
     * @param view    view
     * @param handled handled
     * @return the observable
     */
    @CheckReturnValue
    @NonNull
    public static Observable<SearchBarSearchQueryEvent> searchQueryChangeEvents(
            @NonNull SearchBar view, @NonNull Predicate<? super String> handled) {
        checkNotNull(view, "view == null");
        return new SearchBarQueryChangeEventsOnSubscribe(view, handled);
    }

    /**
     * Create an observable of String values for search query changes on {@code view}.
     * <p>
     * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
     * to free this reference.
     * <p>
     *
     * @param view view
     * @return the observable
     */
    @CheckReturnValue
    @NonNull
    public static Observable<String> searchQueryChanges(@NonNull SearchBar view) {
        checkNotNull(view, "view == null");
        return new SearchBarQueryChangesOnSubscribe(view, PREDICATE_ALWAYS_TRUE);
    }

    /**
     * Flod event observable
     *
     * @param view view
     * @return the observable
     */
    @CheckReturnValue
    @NonNull
    public static Observable<Object> flodEvent(@NonNull SearchBar view) {
        checkNotNull(view, "view == null");
        return new SearchBarFoldOnSubscribe(view, CALLABLE_ALWAYS_TRUE);
    }

    /**
     * Flod event observable
     *
     * @param view    view
     * @param handled handled
     * @return the observable
     */
    @CheckReturnValue
    @NonNull
    public static Observable<Object> flodEvent(@NonNull SearchBar view, Callable<Boolean> handled) {
        checkNotNull(view, "view == null");
        return new SearchBarFoldOnSubscribe(view, handled);
    }

    /**
     * Search query bi consumer
     *
     * @param view view
     * @return the bi consumer
     */
    @CheckReturnValue
    @NonNull
    public static BiConsumer<? super String, ? super Boolean> searchQuery(@NonNull SearchBar view) {
        checkNotNull(view, "view == null");
        return view::setQuery;
    }

    private RxSearchBar() {
        throw new AssertionError("No instances.");
    }
}
